package com.rrd.hive.udf;

import com.rrd.hive.util.StringPadUtil;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

import java.io.UnsupportedEncodingException;

public class NFCSCreditUserApplyInfoUDF extends UDF {
    public Text evaluate(String... arr) throws UnsupportedEncodingException {
        Text text = new Text();
        if (arr[0].equals("user")) {
            text.set(userBaseInfo(arr));
        } else if (arr[0].equals("lend")) {
            text.set(lendinfo(arr));
        } else if (arr[0].equals("loan")) {
            text.set(loanInfo(arr));
        } else if (arr[0].equals("special")) {
            text.set(specialInfo(arr));
        } else if(arr[0].equals("delete")){
        	text.set(deleteInfo(arr));
        }else if(arr[0].equals("guarante")){
        	text.set(guaranteInfo(arr));
        }else if(arr[0].equals("chanage")){
        	text.set(changeAccountInfo(arr));
        }   else {
            System.out.println("未找到匹配的参数！！！！！！！！！！");
            throw new RuntimeException(
                    "第一个参数，必须在('user','lend','loan','special')中");
        }

        return text;

    }

    private String userBaseInfo(String... arr)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        sb.append("P").append(arr[1]);
        //姓名
        sb.append(StringPadUtil.rightPad(arr[2], 30));
        //证件类型
        sb.append(arr[3]);
        //证件号码
        sb.append(StringPadUtil.rightPad(arr[4], 18));
        //信息类别
        sb.append("B");
        //性别
        sb.append(StringPadUtil.leftPad(arr[5], 1));
        //出生日期
        if (arr[6] == null) {
            arr[6] = "19010101";
        }
        sb.append(StringPadUtil.leftPad(arr[6], 8));
        //婚姻状况
        sb.append(StringPadUtil.leftPad(arr[7], 2));
        //高学历
        sb.append(StringPadUtil.leftPad(arr[8], 2));
        //最高学位
        sb.append(StringPadUtil.leftPad(arr[9], 1));
        //住宅电话
        sb.append(StringPadUtil.rightPad(arr[10], 25));
        //手机号码
        sb.append(StringPadUtil.rightPad(arr[11], 16));
        //单位电话
        sb.append(StringPadUtil.rightPad(arr[12], 25));
        //电子邮箱
        sb.append(StringPadUtil.rightPad(arr[13], 30));
        //通讯地址
        sb.append(StringPadUtil.rightPad(arr[14], 60));
        //通讯地址邮政编码
        sb.append(StringPadUtil.rightPad(arr[15], 6));
        //户籍地址
        sb.append(StringPadUtil.rightPad(arr[16], 60));
        //配偶姓名
        sb.append(StringPadUtil.rightPad(arr[17], 30));
        //配偶证件类型
        sb.append(StringPadUtil.rightPad(arr[18], 1));
        //配偶证件号码
        sb.append(StringPadUtil.rightPad(arr[19], 18));
        //配偶工作单位
        sb.append(StringPadUtil.rightPad(arr[20], 60));
        //配偶联系电话
        sb.append(StringPadUtil.rightPad(arr[21], 25));
        //第一联系人姓名
        if (!isLetterDigitOrChinese(arr[22])) {
            arr[22] = "未知";
        }
        sb.append(StringPadUtil.rightPad(arr[22], 30));
        //第一联系人关系
        sb.append(StringPadUtil.rightPad(arr[23], 1));
        //第一联系人电话
        sb.append(StringPadUtil.rightPad(arr[24], 25));
        //第二联系人姓名
        if (!isLetterDigitOrChinese(arr[25])) {
        	arr[25] = "";
            arr[26] = "";
            arr[27] = "";
        }
        sb.append(StringPadUtil.rightPad(arr[25], 30));
        //第二联系人关系
        sb.append(StringPadUtil.rightPad(arr[26], 1));
        //第二联系人电话
        sb.append(StringPadUtil.rightPad(arr[27], 25));
        //职业信息类别
        sb.append("C");
        //职业
        sb.append(StringPadUtil.rightPad(arr[28], 1));
        //单位名称
        sb.append(StringPadUtil.rightPad(arr[29], 60));
        //单位所属行业
        sb.append(StringPadUtil.rightPad(arr[30], 1));
        //单位地址
        sb.append(StringPadUtil.rightPad(arr[31], 60));
        //单位地址邮政编码
        sb.append(StringPadUtil.leftPad(arr[32], 6));
        //本单位工作起始年 份
        sb.append(StringPadUtil.leftPad(arr[33], 4));
        //职务
        sb.append(StringPadUtil.leftPad(arr[34], 1));
        //职称
        sb.append(StringPadUtil.leftPad(arr[35], 1));
        //年收入
        sb.append(StringPadUtil.leftPad(arr[36], 10));
        //居住地址段数据项信息类别
        sb.append("D");
        //居住地址
        sb.append(StringPadUtil.rightPad(arr[37], 60));
        //居住地址邮政编码
        sb.append(StringPadUtil.leftPad(arr[38], 6));
        //居住状况
        sb.append(StringPadUtil.rightPad(arr[39], 1));
        return sb.toString();
    }

    /**
     * 处理借款申请数据
     *
     * @param arr
     * @return
     * @throws UnsupportedEncodingException
     */
    private String lendinfo(String... arr) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        //借款申请信息类别，机构代码
        sb.append("S").append(arr[1]);
        //借款申请号
        sb.append(StringPadUtil.rightPad(arr[2], 40));
        //姓名
        sb.append(StringPadUtil.rightPad(arr[3], 30));
        //证件类型
        sb.append(StringPadUtil.rightPad(arr[4], 1));
        //证件号码
        sb.append(StringPadUtil.rightPad(arr[5], 18));
        //借款申请类型
        sb.append(StringPadUtil.rightPad(arr[6], 2));
        //借款申请金额
        sb.append(StringPadUtil.leftPad(arr[7], 10));
        //借款申请月数
        sb.append(StringPadUtil.leftPad(arr[8], 6));
        //借款申请时间
        sb.append(StringPadUtil.leftPad(arr[9], 8));
        //借款申请状态
        sb.append(StringPadUtil.rightPad(arr[10], 1));
        //贷款业务号
        sb.append(StringPadUtil.rightPad(arr[11], 40));
        //贷款授信额度
        sb.append(StringPadUtil.leftPad(arr[12], 10));
        //贷款综合利率
        
        if(arr[13]==null || arr[13].equals("") || arr[13].equals("\\N") || Double.parseDouble(arr[13])>=0 ){
        	if(arr[13].equals("\\N")){
        		arr[13]="";
        	}
        	sb.append(StringPadUtil.leftPad(arr[13], 5));
        	
        }else{
        	sb.append("-").append(StringPadUtil.leftPad(arr[13].substring(1), 4));
        }
        
        return sb.toString();
    }

    private String loanInfo(String... arr) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        //借款申请信息类别，机构代码
        sb.append("A").append(arr[1]);
        //借款类型
        sb.append(StringPadUtil.rightPad(arr[2], 2));
        //借款合同号码
        sb.append(StringPadUtil.rightPad(arr[3], 60));
        //业务号
        sb.append(StringPadUtil.rightPad(arr[4], 40));
        //发生地点
        sb.append(StringPadUtil.leftPad(arr[5], 6));
        //开户日期
        sb.append(StringPadUtil.leftPad(arr[6], 8));
        //到期日期
        sb.append(StringPadUtil.leftPad(arr[7], 8));
        //币种
        sb.append(StringPadUtil.rightPad(arr[8], 3));
        //授信额度
        sb.append(StringPadUtil.leftPad(arr[9], 10));
        //共享授信额度
        sb.append(StringPadUtil.leftPad(arr[10], 10));
        //最大负债额
        sb.append(StringPadUtil.leftPad(arr[11], 10));
        //担保方式
        sb.append(StringPadUtil.leftPad(arr[12], 1));
        //还款频率
        sb.append(StringPadUtil.rightPad(arr[13], 2));
        //还款月数
        sb.append(StringPadUtil.rightPad(arr[14], 3));
        //剩余还款月数
        sb.append(StringPadUtil.rightPad(arr[15], 3));
        //协定还款期数
        sb.append(StringPadUtil.rightPad(arr[16], 3));
        //协定期还款额
        sb.append(StringPadUtil.rightPad(arr[17], 10));
        //结算/应还款日期
        sb.append(StringPadUtil.leftPad(arr[18], 8));
        //最近一次实际还款 日期
        sb.append(StringPadUtil.leftPad(arr[19], 8));
        //本月应还款金额
        if(!arr[20].equals("") && Double.parseDouble(arr[20])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[20].substring(1, 2),9));
        }else{
        	sb.append(StringPadUtil.leftPad(arr[20], 10));
        }
        
        //本月实际还款金额
        if(!arr[21].equals("") && Double.parseDouble(arr[21])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[21].substring(1, 2),9));
        }else{
        	sb.append(StringPadUtil.leftPad(arr[21], 10));
        }
        
        //余额
        if(!arr[22].equals("") && Double.parseDouble(arr[22])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[22].substring(1, 2),9));
        }else{
        	sb.append(StringPadUtil.leftPad(arr[22], 10));
        }
        
        //当前逾期期数
        sb.append(StringPadUtil.leftPad(arr[23], 2));
        //当前逾期总额
        if(!arr[24].equals("") && Double.parseDouble(arr[24])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[24].substring(1, 2),9));
        }else{
        	sb.append(StringPadUtil.leftPad(arr[24], 10));
        }
        
        //逾期 31-60 天未归还借款本金
        if(!arr[25].equals("") && Double.parseDouble(arr[25])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[25].substring(1, 2),9));
        }else{
        	sb.append(StringPadUtil.leftPad(arr[25], 10));
        }
        
        //逾期 61-90 天未归还借款本金
        if(!arr[26].equals("") && Double.parseDouble(arr[26])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[26].substring(1, 2),9));
        }else{
        	sb.append(StringPadUtil.leftPad(arr[26], 10));
        }
        
        //逾期 91-180 天未归还借款本金
        if(!arr[27].equals("") && Double.parseDouble(arr[27])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[27].substring(1, 2),9));
        }else{
        	sb.append(StringPadUtil.leftPad(arr[27], 10));
        }
        
        //逾期 180 天以上未归还借款本金
        if(!arr[28].equals("") && Double.parseDouble(arr[28])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[28].substring(1, 2),9));
        }else{
        	sb.append(StringPadUtil.leftPad(arr[28], 10));
        }
        
        //累计逾期期数
        sb.append(StringPadUtil.leftPad(arr[29], 3));
        //最高逾期期数
        sb.append(StringPadUtil.leftPad(arr[30], 2));
        //五级分类状态
        sb.append(StringPadUtil.leftPad(arr[31], 1));
        //账户状态
        sb.append(StringPadUtil.leftPad(arr[32], 1));
        //24 月（借款）还款状 态
        sb.append(StringPadUtil.rightPad(arr[33], 24));
        //账户拥有者信息提 示
        sb.append(StringPadUtil.leftPad(arr[34], 1));
        //姓名
        sb.append(StringPadUtil.rightPad(arr[35], 30));
        //证件类型
        sb.append(StringPadUtil.rightPad(arr[36], 1));
        //证件号码
        sb.append(StringPadUtil.rightPad(arr[37], 18));
        //预留字段
        sb.append(StringPadUtil.rightPad(arr[38], 30));

        return sb.toString();
    }

    /**
     * 特殊交易信息报文
     *
     * @param arr
     * @return
     * @throws UnsupportedEncodingException
     */
    private String specialInfo(String... arr)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        //信息类别 机构代码
        sb.append("G").append(arr[1]);
        //姓名
        sb.append(StringPadUtil.rightPad(arr[2], 30));
        //证件类型
        sb.append(StringPadUtil.rightPad(arr[3], 1));
        //证件号码
        sb.append(StringPadUtil.rightPad(arr[4], 18));
        //业务号
        sb.append(StringPadUtil.rightPad(arr[5], 40));
        //特殊交易类型
        sb.append(StringPadUtil.leftPad(arr[6], 1));
        //发生日期
        sb.append(StringPadUtil.rightPad(arr[7], 8));
        //变更月数
        if(!arr[8].equals("") && Integer.parseInt(arr[8])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[8].substring(1), 3));
        }else{
        	 sb.append(StringPadUtil.leftPad(arr[8], 4));
        }
        //发生金额
        if(!arr[9].equals("") && Double.parseDouble(arr[9])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[9].substring(1), 9));
        }else{
        	 sb.append(StringPadUtil.leftPad(arr[9], 10));
        }
        //明细信息
        sb.append(StringPadUtil.rightPad(arr[10], 200));
        return sb.toString();
    }
    /**
     * 删除交易信息报文
     * 
     * @param arr
     * @return
     * @throws UnsupportedEncodingException
     */
    private String deleteInfo(String... arr)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        //信息类别 机构代码
        sb.append(arr[1]);
        //业务号
        sb.append(StringPadUtil.leftPad(arr[2], 40));
      //起始结算/应还款日期
        sb.append(StringPadUtil.leftPad(arr[3], 8));
        //结束结算/应还款日期
        sb.append(StringPadUtil.leftPad(arr[4], 8));
       
        return sb.toString();
    }
    /**
     * 担保信息报文
     * 
     * @param arr
     * @return
     * @throws UnsupportedEncodingException
     */
    private String guaranteInfo(String... arr)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        sb.append("E");
        //担保人姓名
        sb.append(StringPadUtil.rightPad(arr[1], 30));
        //担保人证件类型
        sb.append(StringPadUtil.rightPad(arr[2], 1));
        //担保人证件号码
        sb.append(StringPadUtil.rightPad(arr[3], 18));
        //担保金额
        sb.append(StringPadUtil.leftPad(arr[4], 10));
        //担保状态
        sb.append(StringPadUtil.rightPad(arr[5], 1));
        
        return sb.toString();
    }
    /**
     * 账户标识变更报文
     * 
     * @param arr
     * @return
     * @throws UnsupportedEncodingException
     */
    private String changeAccountInfo(String... arr)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
   
        //原机构代码
        sb.append(StringPadUtil.rightPad(arr[1], 14));
        //原业务号
        sb.append(StringPadUtil.rightPad(arr[2], 40));
        //新机构代码
        sb.append(StringPadUtil.rightPad(arr[3], 14));
        //新业务号
        sb.append(StringPadUtil.rightPad(arr[4], 40));
        
        
        return sb.toString();
    }
    private static boolean isLetterDigitOrChinese(String str) {
        String regex = "^[a-z0-9A-Z\u0020\u3000\uff0c\u002c\uff1f\u003f\u0028\u0029\uff08\uff09\u4e00-\u9fa5]+$";
        return str.matches(regex);
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
    	String s="E友勇信                        061088770086278417300000004501";
    	s="-1.1";
    	System.out.println(s);
    	System.out.println("-"+StringPadUtil.leftPad(s.substring(1), 4));	 
    	System.out.println(Double.parseDouble("-"+StringPadUtil.leftPad(s.substring(1), 4)));
    	System.out.println(Double.parseDouble("-0000002.4530"));
    }
}
